package com.chenliang.juc;

import java.util.concurrent.CountDownLatch;

/**
 * @program: threadpooltest
 * @description: 测试CountDownLatch
 * @author: 陈亮
 * @create: 2022-02-22 21:19
 */
public class CountDownLatchDemo {


    /**
     * 将程序肢解为多个可解决任务, 通过异步解决任务, 因为同步很会使时间进行叠加,异步消耗的时间只是某个消耗时间最长的线程而已
     * 解释: 某个接口查询需要返回10个表数据,每个表查询一秒.接口查询返回给前端至少需要10秒,此时采用10个线程异步查询,某个耗时最长的查询是3秒,
     * 那本次查询耗时也就是3秒了.但是我们至少等10个表结果查询出来才能返回给前端,想这种情况,我们需要使用CountDownLatch,等待10个任务完成查询之后,才返回给前端
     *
     * @param args
     */
    public static void main(String[] args) {

        // 给构造方法给定一个状态数,构造方式实现内部Sync的初始化,和状态数的设置
        CountDownLatch countDownLatch = new CountDownLatch(2);

        // 线程t1
        new Thread(() -> {
            System.out.println(Thread.currentThread().getName() + "正在执行...");
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + "结束");

            countDownLatch.countDown();

        }, "t1").start();

        // 线程t2
        new Thread(() -> {
            System.out.println(Thread.currentThread().getName() + "正在执行...");
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + "结束");

            countDownLatch.countDown();

        }, "t2").start();

        System.out.println("等待 t1 和 t2 执行完成...");

        try {
            // 执行代码的线程再锁存器计数变为0之前一直等待着,除非线程被中断
            //  对countDownLatch的await的调用,内部转为sync.acquireSharedInterruptibly(1)的调用
            // 底层设计AQS的调用,过段时间研究调用链.
            countDownLatch.await();

        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println(Thread.currentThread().getName() + " 完成");

    }
}
